package com.codez.unionpay.netty;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

/**
 * @author codez
 * @createTime 2019-05-18 04:24:09
 */

// 根据netty官网编写的简单聊天服务器
public class NettyServer {

	public static void main(String[] args) throws Exception {
		int port = 8080;
		if (args.length > 0) {
			port = Integer.parseInt(args[0]);
		}

		new NettyServer().start(port);
	}

	// 启动服务器
	public void start(Integer port) {
		
		/**
		 * new NioEventLoopGroup(int); 可以传入参数 ,指定县城数 ,好像默认是cpu核数
		 *        根据构造方法设置的数量,可以实现netty的3种模式 : 单线程,多线程,主从多线程(推荐)
		 */
		NioEventLoopGroup bossGroup = new NioEventLoopGroup(); 
		NioEventLoopGroup workerGroup = new NioEventLoopGroup();
		
		try {
			ServerBootstrap bootstrap = new ServerBootstrap();
			bootstrap.group(bossGroup,workerGroup)   // 使用的线程组,可以只传一个参数,那么共用一个线程组(单线程模式)
					.channel(NioServerSocketChannel.class)
					// initChannel可以注册多个
					.childHandler(new ChannelInitializer<SocketChannel>() {
						@Override
						protected void initChannel(SocketChannel ch) throws Exception {
							ch.pipeline().addLast(new NettyServerHandler());
						}
					})
					.option(ChannelOption.SO_BACKLOG, 128)
					.childOption(ChannelOption.SO_KEEPALIVE, true);
			
			// Bind and start to accept incoming connections.
	        ChannelFuture f = bootstrap.bind(port).sync(); // (7)
	        System.out.println("启动服务器成功!");
	        // Wait until the server socket is closed.
	        // In this example, this does not happen, but you can do that to gracefully
	        // shut down your server.
	        f.channel().closeFuture().sync();
	        System.out.println("关闭服务器!");
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			 workerGroup.shutdownGracefully();
	         bossGroup.shutdownGracefully();
		}
		
	}
}
